home *** CD-ROM | disk | FTP | other *** search
- // -*- C++ -*-
- // $Id: $
- #include <ConsLaw.h>
- #include <MenuSystem.h>
- #include <createHCLSchemes.h>
- #include <createFluxFunc.h>
- #include <createInitFunc.h>
- #include <DrawFD.h>
-
- ConsLaw:: ConsLaw ()
- {
- TRACE("ConsLaw::ConsLaw")
-
- p_value = 0; // gives p=1 field
- }
-
-
- BooLean ConsLaw:: ok () const
- {
- TRACE("ConsLaw::ok")
-
- if (!u.ok())
- errorFP("ConsLaw::ok","u is not rebinded to a field (empty handle)");
- else if (!u->ok())
- errorFP("ConsLaw::ok","u field is not ok");
-
- if (!u_prev.ok())
- errorFP("ConsLaw::ok","u_prev is not rebinded to a field (empty handle)");
- else if (!p->ok())
- errorFP("ConsLaw::ok","u_prev field is not ok");
-
- if (!scheme.ok())
- errorFP("ConsLaw::ok","scheme is not rebinded to a field (empty handle)");
-
- if (!flux.ok())
- errorFP("ConsLaw::ok","flux is not rebinded to a function (empty handle)");
-
- if (!p.ok())
- errorFP("ConsLaw::ok","p is not rebinded to a field (empty handle)");
- else if (!p->ok())
- errorFP("ConsLaw::ok","p field is not ok");
-
- if (time_points_for_plot.getNoMembers() < 1)
- warningFP("ConsLaw::ok","no plots will be made! (no time points given)");
-
- return dpTRUE;
- }
-
- void ConsLaw:: adm (MenuSystem& menu)
- {
- TRACE("ConsLaw::adm")
-
- define (global_menu); // define menu items
- global_menu.prompt(); // prompt the user (read input data)
- scan (global_menu); // load user's input data into the class variables
- }
-
- void ConsLaw:: solveProblem ()
- {
- TRACE("ConsLaw::driver")
-
- if (!ok())
- fatalerrorFP("ConsLaw::driver",
- "object is not properly initialized, have you called adm?");
- setIC (); // set initial conditions
- timeLoop (); // perform time stepping
- }
-
- void ConsLaw:: define (MenuSystem& menu, int level)
- {
- menu.addItem (level,
- "grid",
- "grid",
- "GridLattice::scan syntax",
- "d=1, domain: [0,1] index: [0:20]",
- "S",
- 'g', 'g');
- menu.addItem (level,
- "time parameters",
- "timeprm",
- "TimePrm::scan syntax",
- "dt=0.05, t in [0,0.9]",
- "S",
- 't','t');
- menu.addItem (level,
- "time points for plot",
- "plot_times",
- "Set::scan syntax, eoi: <CR>",
- "0.2 0.5 0.8",
- "S", // improvement: could be intelligent from t in [0:?]
- 'p','p');
- menu.addItem (level,
- "scheme",
- "scheme",
- "classname in HCLSchemes hierarchy",
- "UpwindScheme1D",
- validationString(hierHCLSchemes()),
- 's','s');
- menu.addItem (level,
- "flux function",
- "flux",
- "functor, name in FluxFunc hierarchy",
- "FluxLinear",
- validationString(hierFluxFunc()),
- 'f','f');
- menu.addItem (level,
- "initial function",
- "u0",
- "functor, name in InitFunc hierarchy",
- "InitConst1",
- validationString(hierInitFunc()),
- '0','0');
- menu.addItem (level,
- "uL",
- "uL",
- "value of u(x,t) at the left boundary",
- "1",
- "R1",
- 'l','l');
- menu.addItem (level,
- "p-mean",
- "E[p]",
- "mean value of the p-field (f(u;p))",
- "0",
- "R1",
- 'P','P');
- }
-
- void ConsLaw:: scan (MenuSystem& menu)
- {
- TRACE("ConsLaw::scan")
-
- grid.rebind (new GridLattice(1));
- grid->scan (menu.get("grid"));
-
- u.rebind (new FieldFD (grid(), "u"));
- u_prev.rebind (new FieldFD (grid(), "u_prev"));
-
- tip.scan (menu.get("time parameters"));
-
- // add the end mark ';' to the end (required by TimePrm::scan):
- time_points_for_plot.scan (menu.get("time points for plot") + " ;");
-
- // flux term:
- flux_tp = menu.get("flux function");
- flux.rebind (createFluxFunc(flux_tp,*this));
-
- // initial function
- u0_tp = menu.get("initial function");
- u0.rebind (createInitFunc(u0_tp,*this));
-
- // x=xMin boundary condition:
- uL = menu.get("uL").getReal();
- u->valueIndex(0) = u_prev->valueIndex(0) = uL;
-
- // scheme type:
- scheme_tp = menu.get("scheme");
- scheme.rebind (createHCLSchemes (scheme_tp, *this));
-
- // p-field, set p = exp(p_value):
- p.rebind (new FieldFD (grid(),"p"));
- p_value = menu.get("p-mean").getReal();
- p->fill (exp(p_value));
-
- // plot file name:
- file.open (CaseName);
-
- // write input data for a check:
- }
-
- void ConsLaw:: setIC ()
- {
- TRACE("ConsLaw::setIC")
-
- u_prev() = u0();
- u_prev->valueIndex(grid->getBase(1)) = uL;
-
- // --- find the suitable dt ---
- real dt;
- real pmin, pmax;
- p->minmax (pmin, pmax);
-
- if (flux_tp == "FluxLinear")
- {
- if (tip.Delta() > grid->Delta(1)/pmin)
- dt = grid->Delta(1)/pmin;
- else
- dt = tip.Delta();
- }
- else if (flux_tp == "FluxSimpleBuckleyLeverett" || flux_tp == "FluxBurger")
- dt = grid->Delta(1) / maxFluxDeriv (flux(),0,uL,0,0,0.1,0.1);
- else if (flux_tp == "FluxBuckleyLeverett")
- {
- real pdelta;
- if (pmin == pmax)
- pdelta = 10; // void infinite loop in maxFluxDeriv!
- else if (pmax > pmin)
- pdelta = pmax - pmin;
- else
- errorFP("ConsLaw::setIC","pmax=%f < pmin=%f ....",pmax,pmin);
-
- dt = grid->Delta(1) / maxFluxDeriv (flux(),0,uL,pmin,pmax,
- 0.1,pdelta/10.0);
- }
- tip.setTimeStep (dt); // store the computed dt in the TimePrm object
- }
-
- void ConsLaw:: timeLoop ()
- {
- TRACE("ConsLaw::timeLoop")
-
- tip.initTimeLoop();
- tip.increaseTime();
- while (!tip.finished())
- {
- solveAtThisTimeLevel ();
- saveResults ();
- updateDataStructures ();
-
- tip.increaseTime();
- }
- }
-
- void ConsLaw:: solveAtThisTimeLevel ()
- {
- TRACE("ConsLaw::solveAtThisTimeLevel")
-
- scheme->update ();
-
- // set boundary conditions:
- u->valueIndex(grid->getBase(1)) = uL;
- }
-
- void ConsLaw:: saveResults ()
- {
- TRACE("ConsLaw::saveResults")
-
- // dump plot data values on file casename.pl if any given point of
- // time for plotting is within 0.9*dt from the present time value:
-
- if (time_points_for_plot.within (tip.getTime(), 0.4999*tip.Delta()))
- DrawFD::makeCurvPlot (u(),file,"u(x) for t fixed","u",
- oform("t=%g",tip.getTime()));
- }
-
- void ConsLaw:: updateDataStructures ()
- {
- u_prev() = u();
- }
-
- void ConsLaw:: resultReport ()
- {
- TRACE("ConsLaw::resultReport")
-
- // single line short report of results:
- // area under the u-curve:
-
- int i1 = grid->getBase(1);
- int in = grid->getMaxI(1);
- int i;
- real area = 0.5*u->valueIndex(i1) + 0.5*u->valueIndex(in);
- for (i = 2; i <= in-1; i++)
- area += u->valueIndex(i);
- area *= grid->Delta(1);
-
- s_o << oform("%22s %14s dx=%7.4f, dt=%7.4f, area=%7.4f\n",
- scheme_tp.chars(),flux_tp.chars(),
- grid->Delta(1),tip.Delta(),area);
- }
-
-
- /* LOG HISTORY of this file:
- $Log: $
- */
-